-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Add read_and_decode API based iis3dwb sensor driver #90286
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
76587b9
to
6540c50
Compare
drivers/sensor/st/iis3dwb/Kconfig
Outdated
select SPI | ||
select HAS_STMEMSC | ||
select USE_STDC_IIS3DWB | ||
select RTIO_WORKQ if SENSOR_ASYNC_API |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RTIO_WORKQ should be avoided if possible being selected by every driver, unless the driver is actually using it
drivers/sensor/st/iis3dwb/iis3dwb.c
Outdated
|
||
void iis3dwb_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) | ||
{ | ||
struct rtio_work_req *req = rtio_work_req_alloc(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Work queue seems unneeded here as both one shot and stream paths are fully asynchronous already, unless I've missed something
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
The IIS3DWB is a system-in-package featuring a 3-axis digital vibration sensor with low noise over an ultrawide and flat frequency range. The wide bandwidth, low noise, very stable and repeatable sensitivity, together with the capability of operating over an extended temperature range (up to +105 C), make the device particularly suitable for vibration monitoring in industrial applications. Datasheet: https://www.st.com/en/mems-and-sensors/iis3dwb.html This driver is currently only supporting the polling-mode read_and_decode APIs (both blocking and non-blocking). This driver is based on stmemsc HAL i/f v2.9.1. Signed-off-by: Armando Visconti <armando.visconti@st.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haven't finished a full review, but this should be a good start
drivers/sensor/st/iis3dwb/iis3dwb.c
Outdated
switch (fs) { | ||
case 2: | ||
range = IIS3DWB_DT_FS_2G; | ||
break; | ||
case 4: | ||
range = IIS3DWB_DT_FS_4G; | ||
break; | ||
case 8: | ||
range = IIS3DWB_DT_FS_8G; | ||
break; | ||
case 16: | ||
range = IIS3DWB_DT_FS_16G; | ||
break; | ||
default: | ||
LOG_ERR("fs [%d] not supported.", fs); | ||
return -EINVAL; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While this works for all the sensors I know of we shouldn't be requiring exact values just like we don't require exact values for sample rates, if the used passed 1g for the scale, we should round up to 2 etc. Otherwise you get some strange behavior no? For example:
Passing 9.806650 m/s2 will result in 1g which will be invalid, but should be rounded to 2g.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ack
drivers/sensor/st/iis3dwb/iis3dwb.c
Outdated
default: | ||
odr = IIS3DWB_XL_ODR_26k7Hz; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other drivers only allow rounding up. We should keep that up, if the user asked for 25kHz then serving a higher value is OK, but if the user asks for 100kHz we should fail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here, the idea is that sensor can be either turned on at fixed rate (26.7 khz) or turned off. So, my idea was that the passed odr can be 0 for turning off or any value for turning on. I understand that there is a user API rule to be respected, so I may add a check.
read_reg = rtio_sqe_acquire(rtio); | ||
|
||
if (write_addr == NULL || read_reg == NULL) { | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you need to mark iodev_sqe
as failed here before returning
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ack
|
||
complete_op = rtio_sqe_acquire(rtio); | ||
if (complete_op == NULL) { | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, if you failed to start the next operation set you need to mark the incoming iodev_sqe
as failed and release all the SQEs you've acquired
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ack
rc = rtio_sqe_rx_buf(iodev_sqe, min_buf_len, min_buf_len, &buf, &buf_len); | ||
if (rc != 0) { | ||
LOG_ERR("Failed to get a read buffer of size %u bytes", min_buf_len); | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mark iodev_sqe
as failed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ack
drivers/sensor/st/iis3dwb/iis3dwb.c
Outdated
} | ||
} | ||
|
||
if (edata->has_accel == 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't this fail on SENSOR_CHAN_DIE_TEMP only reads? Do we have to read acceleration to get the die temperature?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, you are right, we don't. We can read temp w/o reading accel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On a second thought, I think it is not possible to have only temperature data. Nevertheless, I find useful to follow your suggestion anyway. Thx
drivers/sensor/st/iis3dwb/iis3dwb.c
Outdated
|
||
static DEVICE_API(sensor, iis3dwb_driver_api) = { | ||
.attr_set = iis3dwb_attr_set, | ||
#ifdef CONFIG_SENSOR_ASYNC_API |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you should use CONFIG_IIS3DWB_STREAM
here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I require it even if STREAM is not defined, I see that 70% of the other drivers are exacting like this, BUT the remaining 30% does not wrap .get_decoder
and .submit
at all. I may follow that 30% of drivers
drivers/sensor/st/iis3dwb/iis3dwb.c
Outdated
do { | ||
iis3dwb_reset_get(ctx, &rst); | ||
} while (rst); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems pretty aggressive, can we use WAIT_FOR
here so there's a deadline?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, I'm looking at its usage
drivers/sensor/st/iis3dwb/iis3dwb.h
Outdated
|
||
#define GAIN_UNIT (61LL) | ||
|
||
#ifdef CONFIG_IIS3DWB_STREAM |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why hide this struct? these #if
in headers make it really difficult to read the header and later make IS_ENABLED(CONFIG_IIS3DWB_STREAM)
impossible to use
edata->has_accel = 1; | ||
|
||
uint8_t outx_regs[] = { IIS3DWB_OUTX_L_A, }; | ||
struct spi_buf buf_xl[] = { {(uint8_t *)edata->accel, 6} }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We shouldn't be using the memory from the driver here, the user should be providing the data with the SQE. If we have the MPU on, this would cause a fault.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But edata is not driver memory; it is allocated few lines above (buf). Can you comment on this?
@yperess Thanks for your review. I'll take care of it as soon as possible. I think this work is important to consolidate and divulgate the read_and_decode approach. At this review stage I also want to ask you a comment about the iis3dwb_rtio_rd_transaction() routine. If you see among his argument there is a spi_buf structure pointer which basically it is used to pass a list of bufp and buf_len. It should be possible to prepare a RTIO buffer chunks reading, e.g. (using same concept in another driver I'm currently developing)
Now I would like to know if
If this can be a good idea I may implement it in this PR at this stage. Let me know. EDIT: |
Add read_and_decode streaming APIs support. Triggers supported: - SENSOR_TRIG_FIFO_WATERMARK - SENSOR_TRIG_FIFO_FULL - SENSOR_TRIG_DATA_READY Signed-off-by: Armando Visconti <armando.visconti@st.com>
|
I think if I'm reading this correctly this API is wanting to do a series of register reads, e.g. read reg X, Y, and Z into values X, Y, Z? I mean this is completely reasonable, and actually I think matches some ideas @ubieda had around a regmap like API on top of RTIO. I'd welcome rtio_regmap.h or some such that provides an API like this to read/write to a register map over a bus easily and with the ability to control blocking/non-blocking like all other RTIO stuff. |
Not sure we are talking about same thing. I will try to prepare a PR in the next week. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What a well written driver
Looking again the the bits here to read the interrupt status register and such though, I think this is very close to what @ubieda was thinking about. I'll try and suggest we discuss this in the next sensor wg if that makes sense to you @avisconti
Yes sure. |
@teburd @ubieda
I noticed that a routine like that can be generally useful for every driver. It will be called in this way:
Please note that spi_buf is not what I woul want to do (bus can be I2C or I3C as well). |
This PR might be changed according to what decision will be taken on #91775, |
The IIS3DWB is a ST 3-axis digital vibration sensor. This PR includes support using read_and_decode APIs for both one shot and streaming capability. The current triggers supported are:
This driver DOES NOT provide support for old fetch_and_get APIs, therefore following
sensor_driver_api
callbacks (as well as trigger's threads support) are not provided:The driver has been tested on a nucleo_h503rb board with a spi-configured x_nucleo_iks01a3 shield. It should be in line with what discussed in #70651